home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Identify.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  19KB  |  973 lines

  1. /*
  2. **    Identify.c
  3. **
  4. **    Heuristic file type identification routines (big words!).
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* The file types we know. */
  17.  
  18. enum    {    TYPE_DIR,TYPE_FILE,
  19.             TYPE_ICON,
  20.             TYPE_TEXT,
  21.             TYPE_C,TYPE_H,
  22.             TYPE_ASM,TYPE_I,
  23.             TYPE_MOD,
  24.             TYPE_REXX,
  25.             TYPE_BASIC,
  26.             TYPE_AMIGAGUIDE,
  27.             TYPE_TEX,TYPE_METAFONT,TYPE_GF,TYPE_TEXFONT,TYPE_TEXDVI,TYPE_FLIB,
  28.             TYPE_OLDMANX,TYPE_NEWMANX,TYPE_OLDMANXLIB,TYPE_NEWMANXLIB,
  29.             TYPE_OBJECT,TYPE_LIB,
  30.             TYPE_EXECUTABLE,
  31.             TYPE_LIBRARY,TYPE_DEVICE,TYPE_FILESYS,TYPE_HANDLER,
  32.             TYPE_GIF,TYPE_DEGAS,TYPE_MACPAINT,TYPE_SUPERPAINT,TYPE_PICT,TYPE_SUNRASTER,TYPE_POSTSCRIPT,TYPE_PCX,TYPE_TIFF,TYPE_BMP,TYPE_JFIF,TYPE_ILBM,
  33.             TYPE_ANIM,TYPE_8SVX,TYPE_SMUS,TYPE_FTXT,TYPE_PREFS,TYPE_TERM,TYPE_AMIGAVISION,TYPE_IFF,
  34.             TYPE_IMPLODER,TYPE_POWERPACKER,TYPE_LHPAK,TYPE_LHASFX,
  35.             TYPE_ARC,TYPE_ARJ,TYPE_COMPRESSED,TYPE_CPIO,TYPE_UUENCODED,TYPE_FREEZE,TYPE_MACCOMPRESS,TYPE_COMPACT,TYPE_DIAMOND,TYPE_LHARC,TYPE_LHA,TYPE_ZOO,TYPE_ZIP,TYPE_STUFFIT,TYPE_PACKIT,TYPE_DMS,TYPE_WARP,TYPE_ZOOM,
  36.             TYPE_SPARCOBJECT,TYPE_SPARCEXECUTABLE,
  37.             TYPE_MSDOSEXECUTABLE,
  38.             TYPE_ATARIEXECUTABLE,
  39.             TYPE_MACEXECUTABLE,
  40.             TYPE_CDAF,TYPE_XPK,
  41.             TYPE_PNG,TYPE_LZX,
  42.  
  43.             TYPE_COUNT
  44.         };
  45.  
  46.     /* Locale string IDs for the file types */
  47.  
  48. UWORD TypeID[TYPE_COUNT] =
  49. {
  50.     MSG_IDENTIFY_FILETYPE_0,
  51.     MSG_IDENTIFY_FILETYPE_1,
  52.     MSG_IDENTIFY_FILETYPE_2,
  53.     MSG_IDENTIFY_FILETYPE_3,
  54.     MSG_IDENTIFY_FILETYPE_4,
  55.     MSG_IDENTIFY_FILETYPE_5,
  56.     MSG_IDENTIFY_FILETYPE_6,
  57.     MSG_IDENTIFY_FILETYPE_7,
  58.     MSG_IDENTIFY_FILETYPE_8,
  59.     MSG_IDENTIFY_FILETYPE_9,
  60.     MSG_IDENTIFY_FILETYPE_10,
  61.     MSG_IDENTIFY_FILETYPE_11,
  62.     MSG_IDENTIFY_FILETYPE_12,
  63.     MSG_IDENTIFY_FILETYPE_13,
  64.     MSG_IDENTIFY_FILETYPE_14,
  65.     MSG_IDENTIFY_FILETYPE_15,
  66.     MSG_IDENTIFY_FILETYPE_16,
  67.     MSG_IDENTIFY_FILETYPE_17,
  68.     MSG_IDENTIFY_FILETYPE_18,
  69.     MSG_IDENTIFY_FILETYPE_19,
  70.     MSG_IDENTIFY_FILETYPE_20,
  71.     MSG_IDENTIFY_FILETYPE_21,
  72.     MSG_IDENTIFY_FILETYPE_22,
  73.     MSG_IDENTIFY_FILETYPE_23,
  74.     MSG_IDENTIFY_FILETYPE_24,
  75.     MSG_IDENTIFY_FILETYPE_25,
  76.     MSG_IDENTIFY_FILETYPE_26,
  77.     MSG_IDENTIFY_FILETYPE_27,
  78.     MSG_IDENTIFY_FILETYPE_28,
  79.     MSG_IDENTIFY_FILETYPE_29,
  80.     MSG_IDENTIFY_FILETYPE_30,
  81.     MSG_IDENTIFY_FILETYPE_31,
  82.     MSG_IDENTIFY_FILETYPE_32,
  83.     MSG_IDENTIFY_FILETYPE_33,
  84.     MSG_IDENTIFY_FILETYPE_34,
  85.     MSG_IDENTIFY_FILETYPE_35,
  86.     MSG_IDENTIFY_FILETYPE_36,
  87.     MSG_IDENTIFY_FILETYPE_37,
  88.     MSG_IDENTIFY_FILETYPE_38,
  89.     MSG_IDENTIFY_FILETYPE_39,
  90.     MSG_IDENTIFY_FILETYPE_40,
  91.     MSG_IDENTIFY_FILETYPE_41,
  92.     MSG_IDENTIFY_FILETYPE_42,
  93.     MSG_IDENTIFY_FILETYPE_43,
  94.     MSG_IDENTIFY_FILETYPE_44,
  95.     MSG_IDENTIFY_FILETYPE_45,
  96.     MSG_IDENTIFY_FILETYPE_46,
  97.     MSG_IDENTIFY_FILETYPE_47,
  98.     MSG_IDENTIFY_FILETYPE_48,
  99.     MSG_IDENTIFY_FILETYPE_49,
  100.     MSG_IDENTIFY_FILETYPE_50,
  101.     MSG_IDENTIFY_FILETYPE_51,
  102.     MSG_IDENTIFY_FILETYPE_52,
  103.     MSG_IDENTIFY_FILETYPE_53,
  104.     MSG_IDENTIFY_FILETYPE_54,
  105.     MSG_IDENTIFY_FILETYPE_55,
  106.     MSG_IDENTIFY_FILETYPE_56,
  107.     MSG_IDENTIFY_FILETYPE_57,
  108.     MSG_IDENTIFY_FILETYPE_58,
  109.     MSG_IDENTIFY_FILETYPE_59,
  110.     MSG_IDENTIFY_FILETYPE_60,
  111.     MSG_IDENTIFY_FILETYPE_61,
  112.     MSG_IDENTIFY_FILETYPE_62,
  113.     MSG_IDENTIFY_FILETYPE_63,
  114.     MSG_IDENTIFY_FILETYPE_64,
  115.     MSG_IDENTIFY_FILETYPE_65,
  116.     MSG_IDENTIFY_FILETYPE_66,
  117.     MSG_IDENTIFY_FILETYPE_67,
  118.     MSG_IDENTIFY_FILETYPE_68,
  119.     MSG_IDENTIFY_FILETYPE_69,
  120.     MSG_IDENTIFY_FILETYPE_70,
  121.     MSG_IDENTIFY_FILETYPE_71,
  122.     MSG_IDENTIFY_FILETYPE_72,
  123.     MSG_IDENTIFY_FILETYPE_73,
  124.     MSG_IDENTIFY_CDAF,
  125.     MSG_IDENTIFY_XPK,
  126.     MSG_IDENTIFY_FILETYPE_74,
  127.     MSG_IDENTIFY_FILETYPE_75
  128. };
  129.  
  130.     /* File type/class mappings. */
  131.  
  132. STATIC WORD FileTypes[TYPE_COUNT] =
  133. {
  134.     FILETYPE_DIR,
  135.     FILETYPE_FILE,
  136.     FILETYPE_NONE,
  137.     FILETYPE_TEXT,
  138.     FILETYPE_TEXT,
  139.     FILETYPE_TEXT,
  140.     FILETYPE_TEXT,
  141.     FILETYPE_TEXT,
  142.     FILETYPE_TEXT,
  143.     FILETYPE_TEXT,
  144.     FILETYPE_TEXT,
  145.     FILETYPE_TEXT,
  146.     FILETYPE_TEXT,
  147.     FILETYPE_FILE,
  148.     FILETYPE_FILE,
  149.     FILETYPE_FILE,
  150.     FILETYPE_FILE,
  151.     FILETYPE_FILE,
  152.     FILETYPE_FILE,
  153.     FILETYPE_FILE,
  154.     FILETYPE_FILE,
  155.     FILETYPE_FILE,
  156.     FILETYPE_FILE,
  157.     FILETYPE_FILE,
  158.     FILETYPE_PROGRAM,
  159.     FILETYPE_FILE,
  160.     FILETYPE_FILE,
  161.     FILETYPE_FILE,
  162.     FILETYPE_FILE,
  163.     FILETYPE_PICTURE,
  164.     FILETYPE_PICTURE,
  165.     FILETYPE_PICTURE,
  166.     FILETYPE_PICTURE,
  167.     FILETYPE_PICTURE,
  168.     FILETYPE_PICTURE,
  169.     FILETYPE_PICTURE,
  170.     FILETYPE_PICTURE,
  171.     FILETYPE_PICTURE,
  172.     FILETYPE_PICTURE,
  173.     FILETYPE_PICTURE,
  174.     FILETYPE_PICTURE,
  175.     FILETYPE_PICTURE,
  176.     FILETYPE_SOUND,
  177.     FILETYPE_SOUND,
  178.     FILETYPE_TEXT,
  179.     FILETYPE_PREFS,
  180.     FILETYPE_PREFS,
  181.     FILETYPE_FILE,
  182.     FILETYPE_FILE,
  183.     FILETYPE_ARCHIVE,
  184.     FILETYPE_ARCHIVE,
  185.     FILETYPE_ARCHIVE,
  186.     FILETYPE_ARCHIVE,
  187.     FILETYPE_ARCHIVE,
  188.     FILETYPE_ARCHIVE,
  189.     FILETYPE_ARCHIVE,
  190.     FILETYPE_ARCHIVE,
  191.     FILETYPE_TEXT,
  192.     FILETYPE_ARCHIVE,
  193.     FILETYPE_ARCHIVE,
  194.     FILETYPE_ARCHIVE,
  195.     FILETYPE_ARCHIVE,
  196.     FILETYPE_ARCHIVE,
  197.     FILETYPE_ARCHIVE,
  198.     FILETYPE_ARCHIVE,
  199.     FILETYPE_ARCHIVE,
  200.     FILETYPE_ARCHIVE,
  201.     FILETYPE_ARCHIVE,
  202.     FILETYPE_ARCHIVE,
  203.     FILETYPE_ARCHIVE,
  204.     FILETYPE_ARCHIVE,
  205.     FILETYPE_PROGRAM,
  206.     FILETYPE_PROGRAM,
  207.     FILETYPE_PROGRAM,
  208.     FILETYPE_PROGRAM,
  209.     FILETYPE_PROGRAM,
  210.     FILETYPE_ARCHIVE,
  211.     FILETYPE_ARCHIVE,
  212.     FILETYPE_PICTURE,
  213.     FILETYPE_ARCHIVE
  214. };
  215.  
  216.     /* File class icon names. */
  217.  
  218. STATIC STRPTR ClassIconNames[FILETYPE_COUNT] =
  219. {
  220.     NULL,
  221.     "ENV:sys/def_drawer",
  222.     "ENV:sys/def_project",
  223.     "ENV:sys/def_text",
  224.     "ENV:sys/def_sound",
  225.     "ENV:sys/def_picture",
  226.     "ENV:sys/def_pref",
  227.     "ENV:sys/def_archive",
  228.     "ENV:sys/def_tool",
  229. };
  230.  
  231.     /* A structure containing both a file name suffix and the
  232.      * appropriate file type.
  233.      */
  234.  
  235. struct Suffix
  236. {
  237.     UBYTE    *Name;
  238.     UBYTE     Type;
  239. };
  240.  
  241.     /* A table of valid ASCII characters (7 bits). */
  242.  
  243. STATIC BYTE ID_ValidTab[256] =
  244. {
  245.     0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,
  246.     0,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,
  247.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  248.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  249.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  250.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  251.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  252.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  253.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  254.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  255.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  256.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  257.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  258.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  259.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  260.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  261. };
  262.  
  263.     /* A table of clearly invalid ASCII characters (8 bits). */
  264.  
  265. STATIC BYTE ID_InvalidTab[256] =
  266. {
  267.     1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1,
  268.     1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,
  269.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  270.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  271.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  272.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  273.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  274.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  275.     1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  276.     1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,
  277.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  278.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  279.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  280.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  281.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  282.     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  283. };
  284.  
  285.     /* Some file name suffixes for text files and the appropriate
  286.      * file types.
  287.      */
  288.  
  289. STATIC struct Suffix TextSuffix[] =
  290. {
  291.     ".C",        TYPE_C,
  292.     ".CPP",        TYPE_C,
  293.     ".CXX",        TYPE_C,
  294.     ".C++",        TYPE_C,
  295.     ".CC",        TYPE_C,
  296.     ".H",        TYPE_H,
  297.     ".ASM",        TYPE_ASM,
  298.     ".A",        TYPE_ASM,
  299.     ".S",        TYPE_ASM,
  300.     ".I",        TYPE_I,
  301.     ".BAS",        TYPE_BASIC,
  302.     ".GFA",        TYPE_BASIC,
  303.     ".REXX",    TYPE_REXX,
  304.     ".CED",        TYPE_REXX,
  305.     ".TTX",        TYPE_REXX,
  306.     ".VLT",        TYPE_REXX,
  307.     ".CPR",        TYPE_REXX,
  308.     ".TxEd",    TYPE_REXX,
  309.     ".ADPro",    TYPE_REXX,
  310.     ".TEX",        TYPE_TEX,
  311.     ".STY",        TYPE_TEX,
  312.     ".MF",        TYPE_METAFONT,
  313.     ".MOD",        TYPE_MOD,
  314.     ".DEF",        TYPE_MOD,
  315.     ".PS",        TYPE_POSTSCRIPT,
  316.     ".GUIDE",    TYPE_AMIGAGUIDE,
  317.     ".UUE",        TYPE_UUENCODED
  318. };
  319.  
  320.     /* Some more file name suffixes for executable files and the
  321.      * appropriate file types.
  322.      */
  323.  
  324. STATIC struct Suffix ExecutableSuffix[] =
  325. {
  326.     ".device",    TYPE_DEVICE,
  327.     ".library",    TYPE_LIBRARY,
  328.     "FileSystem",    TYPE_FILESYS,
  329.     "Handler",    TYPE_HANDLER
  330. };
  331.  
  332.     /* Miscellaneous magic cookies. */
  333.  
  334. STATIC STRPTR MagicCookies[] =
  335. {
  336.     "P1",
  337.     "P2",
  338.     "P3",
  339.     "P4",
  340.     "P5",
  341.     "P6",
  342.     "begin",
  343.     "xbtoa"
  344. };
  345.  
  346.     /* LongCompare(UBYTE *Buffer,ULONG Value):
  347.      *
  348.      *    Compare space in memory with a longword value.
  349.      */
  350.  
  351. STATIC BOOL
  352. LongCompare(UBYTE *Buffer,ULONG Value)
  353. {
  354.     UBYTE *OtherBuffer = (UBYTE *)&Value,i;
  355.  
  356.     for(i = 0 ; i < 4 ; i++)
  357.     {
  358.         if(OtherBuffer[i] != Buffer[i])
  359.             return(FALSE);
  360.     }
  361.  
  362.     return(TRUE);
  363. }
  364.  
  365.     /* GetFileType(STRPTR Name,BOOL AttachComment):
  366.      *
  367.      *    Simple routine to identify a file type by looking at
  368.      *    its first 400 bytes. If successful a comment is
  369.      *    attached to the file describing the file type.
  370.      */
  371.  
  372. LONG
  373. GetFileType(STRPTR Name,BOOL AttachComment)
  374. {
  375.     UBYTE IFFType[5];
  376.     STRPTR TypeName;
  377.     ULONG *Buffer;
  378.     LONG i,Len;
  379.     LONG Type;
  380.  
  381.     Type        = TYPE_FILE;
  382.     TypeName    = NULL;
  383.     Len            = strlen(Name);
  384.  
  385.         /* Allocate a buffer for the first 410 bytes of the
  386.          * file.
  387.          */
  388.  
  389.     if(Buffer = (ULONG *)AllocVecPooled(410,MEMF_ANY | MEMF_CLEAR))
  390.     {
  391.         BPTR File,Size;
  392.  
  393.             /* Open the file. */
  394.  
  395.         if(File = Open(Name,MODE_OLDFILE))
  396.         {
  397.                 /* Read the first 410 bytes. */
  398.  
  399.             if((Size = Read(File,Buffer,410)) >= sizeof(ULONG))
  400.             {
  401.                 UBYTE *CharBuffer;
  402.                 LONG Count;
  403.  
  404.                 CharBuffer = (UBYTE *)Buffer;
  405.                 Count = 0;
  406.  
  407.                     /* See if it's an ASCII file. */
  408.  
  409.                 for(i = 0 ; i < Size ; i++)
  410.                 {
  411.                     if(ID_ValidTab[CharBuffer[i]])
  412.                         Count++;
  413.                     else
  414.                     {
  415.                         if(ID_InvalidTab[CharBuffer[i]])
  416.                         {
  417.                             Count = 0;
  418.  
  419.                             break;
  420.                         }
  421.                     }
  422.                 }
  423.  
  424.                     /* If more than 75% of the
  425.                      * characters in the first
  426.                      * 400 bytes are legal
  427.                      * ASCII characters this
  428.                      * file is supposed to be
  429.                      * a text file.
  430.                      */
  431.  
  432.                 if(Count > 3 * (Size / 4))
  433.                     Type = TYPE_TEXT;
  434.  
  435.                     /* Examine the first longword. */
  436.  
  437.                 if(Type == TYPE_FILE)
  438.                 {
  439.                     switch(Buffer[0])
  440.                     {
  441.                         case 0x4C5A5800:
  442.  
  443.                             Type = TYPE_LZX;
  444.                             break;
  445.  
  446.                         case 0x58504B46:
  447.  
  448.                             Type = TYPE_XPK;
  449.                             break;
  450.  
  451.                         case 0x000003E7:
  452.  
  453.                             Type = TYPE_OBJECT;
  454.                             break;
  455.  
  456.                         case 0x000003F3:
  457.  
  458.                             if(Buffer[10] == 'LSFX')
  459.                                 Type = TYPE_LHPAK;
  460.                             else
  461.                             {
  462.                                 if(Buffer[11] == 'SFX!')
  463.                                     Type = TYPE_LHASFX;
  464.                                 else
  465.                                     Type = TYPE_EXECUTABLE;
  466.                             }
  467.  
  468.                             break;
  469.  
  470.                         case 0x000003FA:
  471.  
  472.                             Type = TYPE_LIB;
  473.                             break;
  474.  
  475.                         case 0xF7593647:
  476.  
  477.                             Type = TYPE_TEXFONT;
  478.                             break;
  479.  
  480.                         case 0xF7020183:
  481.  
  482.                             Type = TYPE_TEXDVI;
  483.                             break;
  484.  
  485.                         case 0xF7832020:
  486.  
  487.                             Type = TYPE_GF;
  488.                             break;
  489.  
  490.                         case 0x504B0304:
  491.  
  492.                             Type = TYPE_ZIP;
  493.                             break;
  494.  
  495.                         case 0x01030107:
  496.  
  497.                             Type = TYPE_SPARCOBJECT;
  498.                             break;
  499.  
  500.                         case 0x8103010B:
  501.  
  502.                             Type = TYPE_SPARCEXECUTABLE;
  503.                             break;
  504.  
  505.                         case 0x59A66A95:
  506.  
  507.                             Type = TYPE_SUNRASTER;
  508.                             break;
  509.  
  510.                         case 0x1F9D902A:
  511.  
  512.                             Type = TYPE_COMPRESSED;
  513.                             break;
  514.  
  515.                         case 0x30373037:
  516.  
  517.                             Type = TYPE_CPIO;
  518.                             break;
  519.  
  520.                         case 'FLIB':
  521.  
  522.                             Type = TYPE_FLIB;
  523.                             break;
  524.  
  525.                         case '\211PNG':
  526.  
  527.                             Type = TYPE_PNG;
  528.                             break;
  529.  
  530.                         case 'FORM':
  531.  
  532.                             switch(Buffer[2])
  533.                             {
  534.                                 case 'ILBM':
  535.  
  536.                                     Type = TYPE_ILBM;
  537.                                     break;
  538.  
  539.                                 case 'ANIM':
  540.  
  541.                                     Type = TYPE_ANIM;
  542.                                     break;
  543.  
  544.                                 case '8SVX':
  545.  
  546.                                     Type = TYPE_8SVX;
  547.                                     break;
  548.  
  549.                                 case 'SMUS':
  550.  
  551.                                     Type = TYPE_SMUS;
  552.                                     break;
  553.  
  554.                                 case 'FTXT':
  555.  
  556.                                     Type = TYPE_FTXT;
  557.                                     break;
  558.  
  559.                                 case 'PREF':
  560.  
  561.                                     Type = TYPE_PREFS;
  562.                                     break;
  563.  
  564.                                 case 'TERM':
  565.  
  566.                                     Type = TYPE_TERM;
  567.                                     break;
  568.  
  569.                                 case 'AVCF':
  570.  
  571.                                     Type = TYPE_AMIGAVISION;
  572.                                     break;
  573.  
  574.                                 case 'CDAF':
  575.  
  576.                                     Type = TYPE_CDAF;
  577.                                     break;
  578.  
  579.                                 default:
  580.  
  581.                                     Type = TYPE_IFF;
  582.  
  583.                                     CopyMem(&Buffer[2],IFFType,4);
  584.  
  585.                                     IFFType[4] = 0;
  586.  
  587.                                     break;
  588.                             }
  589.  
  590.                             break;
  591.  
  592.                         case 'IMP!':
  593.  
  594.                             Type = TYPE_IMPLODER;
  595.                             break;
  596.  
  597.                         case 'PP20':
  598.  
  599.                             Type = TYPE_POWERPACKER;
  600.                             break;
  601.  
  602.                         case 'DMS!':
  603.  
  604.                             Type = TYPE_DMS;
  605.                             break;
  606.  
  607.                         case 'Warp':
  608.  
  609.                             Type = TYPE_WARP;
  610.                             break;
  611.  
  612.                         case 'ZOM5':
  613.                         case 'ZOOM':
  614.  
  615.                             Type = TYPE_ZOOM;
  616.                             break;
  617.  
  618.                         case 'ZOO ':
  619.  
  620.                             Type = TYPE_ZOO;
  621.                             break;
  622.  
  623.                         case 'GIF8':
  624.  
  625.                             Type = TYPE_GIF;
  626.                             break;
  627.                     }
  628.                 }
  629.  
  630.                     /* Now for oddly placed magic cookies... */
  631.  
  632.                 if(Type == TYPE_FILE)
  633.                 {
  634.                         /* Dumb check for PCX (awful header -- just
  635.                          * a single byte indicates that the file
  636.                          * is supposed to be a PCX file! Those
  637.                          * PC guys just don't have any
  638.                          * decent software culture!).
  639.                          */
  640.  
  641.                     if(CharBuffer[0] == 0x0A)
  642.                         Type = TYPE_PCX;
  643.  
  644.                         /* Yet another awful file format... */
  645.  
  646.                     if(CharBuffer[0] == 'B' && CharBuffer[1] == 'M')
  647.                         Type = TYPE_BMP;
  648.  
  649.                         /* Check for JFIF... */
  650.  
  651.                     if(LongCompare(&CharBuffer[6],'JFIF'))
  652.                         Type = TYPE_JFIF;
  653.  
  654.                         /* Check for `freeze' output file. */
  655.  
  656.                     if(CharBuffer[0] == (UBYTE)'\037' && CharBuffer[1] >= (UBYTE)'\236')
  657.                         Type = TYPE_FREEZE;
  658.                 }
  659.  
  660.                     /* Check for Macintosh data (note:
  661.                      * this code assumes that the Mac
  662.                      * binary header is still present,
  663.                      * so if you are dealing with stripped
  664.                      * binary files, don't expect the
  665.                      * following code to work!).
  666.                      */
  667.  
  668.                 if(Type == TYPE_FILE)
  669.                 {
  670.                     UBYTE *ByteBuffer = &((UBYTE *)Buffer)[65];
  671.  
  672.                         /* Check for MacPaint... */
  673.  
  674.                     if(LongCompare(ByteBuffer,'PNTG'))
  675.                         Type = TYPE_MACPAINT;
  676.  
  677.                         /* Check for SuperPaint... */
  678.  
  679.                     if(LongCompare(ByteBuffer,'SPTG'))
  680.                         Type = TYPE_SUPERPAINT;
  681.  
  682.                         /* Check for PICT... */
  683.  
  684.                     if(LongCompare(ByteBuffer,'PICT'))
  685.                         Type = TYPE_PICT;
  686.  
  687.                         /* Check for executable... */
  688.  
  689.                     if(LongCompare(ByteBuffer,'APPL') || LongCompare(ByteBuffer,'PRES') || LongCompare(ByteBuffer,'FDOC') || LongCompare(ByteBuffer,'cdev') || LongCompare(ByteBuffer,'INIT'))
  690.                         Type = TYPE_MACEXECUTABLE;
  691.  
  692.                         /* Check for StuffIt archive... */
  693.  
  694.                     if(LongCompare(ByteBuffer,'SIT!') || LongCompare(ByteBuffer,'SIT2'))
  695.                         Type = TYPE_STUFFIT;
  696.  
  697.                         /* Check for PackIt archive... */
  698.  
  699.                     if(LongCompare(ByteBuffer,'PIT '))
  700.                         Type = TYPE_PACKIT;
  701.  
  702.                         /* Check for self-extracting Compact archive. */
  703.  
  704.                     if(LongCompare(ByteBuffer,'APPL') && LongCompare(&ByteBuffer[4],'EXTR'))
  705.                         Type = TYPE_COMPACT;
  706.  
  707.                         /* Check for MacCompress archive. */
  708.  
  709.                     if(LongCompare(ByteBuffer,'ZIVM'))
  710.                         Type = TYPE_MACCOMPRESS;
  711.  
  712.                         /* Check for LhArc archive with MacBinary header. */
  713.  
  714.                     if(LongCompare(ByteBuffer,'LARC'))
  715.                         Type = TYPE_LHARC;
  716.  
  717.                         /* Check for Compact archive. */
  718.  
  719.                     if(LongCompare(ByteBuffer,'PACT'))
  720.                         Type = TYPE_COMPACT;
  721.  
  722.                         /* Check for Diamond archive. */
  723.  
  724.                     if(LongCompare(ByteBuffer,'Pack'))
  725.                         Type = TYPE_DIAMOND;
  726.                 }
  727.  
  728.                     /* Still no match? Have another try... */
  729.  
  730.                 if(Type == TYPE_FILE)
  731.                 {
  732.                     if((Buffer[0] & 0x0000FFFF) == 0x00002D6C && (Buffer[1] & 0xFF00FF00) == 0x68002D00)
  733.                     {
  734.                         if(CharBuffer[5] == '5')
  735.                             Type = TYPE_LHA;
  736.                         else
  737.                             Type = TYPE_LHARC;
  738.                     }
  739.                     else
  740.                     {
  741.                         switch(Buffer[0] & 0xFFFF0000)
  742.                         {
  743.                             case 0x4D4D0000:
  744.                             case 0x49490000:
  745.  
  746.                                 Type = TYPE_TIFF;
  747.                                 break;
  748.  
  749.                             case 0x1A080000:
  750.  
  751.                                 Type = TYPE_ARC;
  752.                                 break;
  753.  
  754.                             case 0x60EA0000:
  755.  
  756.                                 Type = TYPE_ARJ;
  757.                                 break;
  758.  
  759.                             case 0x434A0000:
  760.  
  761.                                 Type = TYPE_NEWMANX;
  762.                                 break;
  763.  
  764.                             case 0x414A0000:
  765.  
  766.                                 Type = TYPE_OLDMANX;
  767.                                 break;
  768.  
  769.                             case 0x636A0000:
  770.  
  771.                                 Type = TYPE_NEWMANXLIB;
  772.                                 break;
  773.  
  774.                             case 0x616A0000:
  775.  
  776.                                 Type = TYPE_OLDMANXLIB;
  777.                                 break;
  778.  
  779.                             case 0xF5000000:
  780.  
  781.                                 Type = TYPE_BASIC;
  782.                                 break;
  783.  
  784.                             case 0xE3100000:
  785.  
  786.                                 Type = TYPE_ICON;
  787.                                 break;
  788.  
  789.                             case 0x4D5A0000:
  790.  
  791.                                 Type = TYPE_MSDOSEXECUTABLE;
  792.                                 break;
  793.  
  794.                             case 0x601A0000:
  795.  
  796.                                 Type = TYPE_ATARIEXECUTABLE;
  797.                                 break;
  798.  
  799.                             case 0x80000000:
  800.  
  801.                                 Type = TYPE_DEGAS;
  802.                                 break;
  803.                         }
  804.                     }
  805.                 }
  806.  
  807.                     /* Take a look at the file name
  808.                      * suffixes.
  809.                      */
  810.  
  811.                 switch(Type)
  812.                 {
  813.                     case TYPE_TEXT:
  814.  
  815.                         for(i = 0 ; i < sizeof(TextSuffix) / sizeof(struct Suffix) ; i++)
  816.                         {
  817.                             Size = strlen(TextSuffix[i].Name);
  818.  
  819.                             if(Len >= Size)
  820.                             {
  821.                                 if(!Stricmp(&Name[Len - Size],TextSuffix[i].Name))
  822.                                 {
  823.                                     Type = TextSuffix[i].Type;
  824.                                     break;
  825.                                 }
  826.                             }
  827.                         }
  828.  
  829.                             /* Is it still a text file? */
  830.  
  831.                         if(Type == TYPE_TEXT)
  832.                         {
  833.                                 /* Check for magic cookies. */
  834.  
  835.                             for(i = 0 ; i < sizeof(MagicCookies) / sizeof(STRPTR) ; i++)
  836.                             {
  837.                                 if(!memcmp(CharBuffer,MagicCookies[i],strlen(MagicCookies[i])))
  838.                                 {
  839.                                     TypeName = LocaleString(MSG_IDENTIFY_COOKIE_0 + i);
  840.  
  841.                                     break;
  842.                                 }
  843.                             }
  844.                         }
  845.  
  846.                         break;
  847.  
  848.                     case TYPE_EXECUTABLE:
  849.  
  850.                         for(i = 0 ; i < sizeof(ExecutableSuffix) / sizeof(struct Suffix) ; i++)
  851.                         {
  852.                             Size = strlen(ExecutableSuffix[i].Name);
  853.  
  854.                             if(Len >= Size)
  855.                             {
  856.                                 if(!Stricmp(&Name[Len - Size],ExecutableSuffix[i].Name))
  857.                                 {
  858.                                     Type = ExecutableSuffix[i].Type;
  859.                                     break;
  860.                                 }
  861.                             }
  862.                         }
  863.  
  864.                         break;
  865.  
  866.                     case TYPE_OBJECT:
  867.  
  868.                         if(Len >= 4)
  869.                         {
  870.                             if(!Stricmp(&Name[Len - 4],".LIB"))
  871.                                 Type = TYPE_LIB;
  872.                         }
  873.  
  874.                         break;
  875.                 }
  876.             }
  877.  
  878.             Close(File);
  879.         }
  880.  
  881.         FreeVecPooled(Buffer);
  882.     }
  883.  
  884.     if(AttachComment)
  885.     {
  886.         if(Type > TYPE_FILE || TypeName)
  887.         {
  888.             if(Type == TYPE_IFF)
  889.             {
  890.                 UBYTE NameBuffer[MAX_FILENAME_LENGTH];
  891.  
  892.                 LimitedSPrintf(sizeof(NameBuffer),NameBuffer,LocaleString(MSG_IDENTIFY_IFF_FILE),IFFType);
  893.  
  894.                 SetComment(Name,NameBuffer);
  895.             }
  896.             else
  897.             {
  898.                 if(TypeName)
  899.                     SetComment(Name,TypeName);
  900.                 else
  901.                     SetComment(Name,LocaleString(TypeID[Type - TYPE_ICON]));
  902.             }
  903.         }
  904.  
  905.             /* Is it an executable file? */
  906.  
  907.         if(Type != TYPE_EXECUTABLE && Type != TYPE_LHPAK && Type != TYPE_LHASFX)
  908.             AddProtection(Name,FIBF_EXECUTE);
  909.     }
  910.  
  911.     return(Type);
  912. }
  913.  
  914.     /* Identify(STRPTR Name):
  915.      *
  916.      *    Try to identify the type of a file,
  917.      *    attach an icon if necessary.
  918.      */
  919.  
  920. VOID
  921. Identify(STRPTR Name,BOOL AttachComment)
  922. {
  923.     LONG Type = GetFileType(Name,AttachComment);
  924.  
  925.     if(Config->MiscConfig->CreateIcons)
  926.         AddIcon(Name,FileTypes[Type],FALSE);
  927. }
  928.  
  929.     /* AddIcon(STRPTR Name,LONG Type,BOOL Override):
  930.      *
  931.      *    Add an icon to a file.
  932.      */
  933.  
  934. VOID
  935. AddIcon(STRPTR Name,LONG Index,BOOL Override)
  936. {
  937.     if(ClassIconNames[Index] && IconBase)
  938.     {
  939.         struct DiskObject *Icon;
  940.  
  941.         if(!Override)
  942.         {
  943.             if(Icon = GetDiskObject(Name))
  944.             {
  945.                 FreeDiskObject(Icon);
  946.  
  947.                 return;
  948.             }
  949.         }
  950.  
  951.         if(!(Icon = GetDiskObject(ClassIconNames[Index])))
  952.         {
  953.             if(Index == FILETYPE_PROGRAM)
  954.                 Icon = GetDefDiskObject(WBTOOL);
  955.             else
  956.             {
  957.                 AddProtection(Name,FIBF_EXECUTE);
  958.  
  959.                 Icon = GetDiskObjectNew(Name);
  960.             }
  961.         }
  962.  
  963.         if(Icon)
  964.         {
  965.             Icon->do_CurrentX = Icon->do_CurrentY = NO_ICON_POSITION;
  966.  
  967.             PutDiskObject(Name,Icon);
  968.  
  969.             FreeDiskObject(Icon);
  970.         }
  971.     }
  972. }
  973.